
#include "Base.h"

#include "GLES2SpriteBatch.h"
#include "Maths/Vector2.h"
#include "Graphics/Textures/Texture.h"
#include "Maths\Rectangle.h"
#include "Graphics/SpriteTypes.h"
#include "Graphics/Renderer/Renderer.h"
#include <gl\gl.h>
#include "Extensions\glext.h"
#include "GLES2Macro.h"
#include "GLES2Texture.h"
#include "Maths\Math.h"

namespace CasaEngine
{

	GLES2SpriteBatch::GLES2SpriteBatch(const IRenderer* renderer_) :
		m_pRenderer(renderer_)
	{
		
	}

	GLES2SpriteBatch::~GLES2SpriteBatch()
	{
	}

	void GLES2SpriteBatch::Begin(int flags)
	{
		GLint iViewport[4];

		GLCheck(glGetIntegerv(GL_VIEWPORT, iViewport ));
		GLCheck(glMatrixMode(GL_PROJECTION));
		GLCheck(glPushMatrix());
		GLCheck(glLoadIdentity());
		GLCheck(glOrtho( iViewport[0], iViewport[0]+iViewport[2],
			iViewport[1]+iViewport[3], iViewport[1], -1, 1 ));

		GLCheck(glDisable(GL_DEPTH_TEST));
		GLCheck(glDisable(GL_LIGHTING));
		GLCheck(glEnable(GL_TEXTURE_2D));
		Renderer.SetupAlphaBlending(Blend::SrcAlpha, Blend::InvSrcAlpha);
		Renderer.SetupTextureUnit(0, TextureOperation::Modulate, TXA_TEXTURE, TXA_DIFFUSE);
		Renderer.SetupTextureUnit(0, TextureOperation::AlphaModulate, TXA_TEXTURE, TXA_DIFFUSE);
		Renderer.Enable(RenderParameter::AlphaBlend, true);
		Renderer.Enable(RenderParameter::ZWrite, false);
	}

	void GLES2SpriteBatch::End()
	{
		GLCheck(glMatrixMode(GL_PROJECTION));
		GLCheck(glPopMatrix());
		GLCheck(glMatrixMode(GL_MODELVIEW));
		GLCheck(glPopMatrix());

		GLCheck(glDisable(GL_TEXTURE_2D));
		//glEnable(GL_BLEND);

		Renderer.Enable(RenderParameter::ZWrite, true);
		Renderer.Enable(RenderParameter::AlphaBlend, false);
	}

	void GLES2SpriteBatch::Draw(
		ITextureBase *Texture2D,
		CRectangle &PositionInTexture,
		Vector2I &Origin,
		Vector2F &Position,
		float Rotation,
		Vector2F &Scale,
		CColor &Color,
		float ZOrder,
		eSpriteEffects SpriteEffect)
	{
		CGLES2Texture *pTexture = dynamic_cast<CGLES2Texture *>(Texture2D);

		if (pTexture == NULL)
		{
			throw new CArgumentException("GLES2SpriteBatch::Draw() : ITextureBase is not a CGLES2Texture object");
		}		

		GLCheck(glMatrixMode(GL_MODELVIEW));
		GLCheck(glPushMatrix());
		GLCheck(glLoadIdentity());
		GLCheck(glScalef(Scale.x, Scale.y, 0.0f));
		GLCheck(glTranslated(Position.x, Position.y, 0));
		GLCheck(glRotatef(MATH_ToDegree(Rotation), 0.0f, 0.0f, 1.0f));
		GLCheck(glTranslated(-Origin.x, -Origin.y, 0));		

		GLCheck(glBindTexture(GL_TEXTURE_2D, pTexture->GetGLES2Texture()));

		GLCheck(glColor4ub(Color.GetRed(), Color.GetGreen(), Color.GetBlue(), Color.GetAlpha()));

		glBegin(GL_QUADS);

			glTexCoord2f((GLfloat)PositionInTexture.Left() / (GLfloat)pTexture->GetSize().x,
				(GLfloat)PositionInTexture.Top() / (GLfloat)pTexture->GetSize().y);
			glVertex2f((GLfloat)PositionInTexture.Left(), (GLfloat)PositionInTexture.Top());

			glTexCoord2f((GLfloat)PositionInTexture.Right() / (GLfloat)pTexture->GetSize().x,
				(GLfloat)PositionInTexture.Top() / (GLfloat)pTexture->GetSize().y);
			glVertex2f((GLfloat)PositionInTexture.Right(), (GLfloat)PositionInTexture.Top());

			glTexCoord2f((GLfloat)PositionInTexture.Right() / (GLfloat)pTexture->GetSize().x,
				(GLfloat)PositionInTexture.Bottom() / (GLfloat)pTexture->GetSize().y);
			glVertex2f((GLfloat)PositionInTexture.Right(), (GLfloat)PositionInTexture.Bottom());

			glTexCoord2f((GLfloat)PositionInTexture.Left() / (GLfloat)pTexture->GetSize().x,
				(GLfloat)PositionInTexture.Bottom() / (GLfloat)pTexture->GetSize().y);
			glVertex2f((GLfloat)PositionInTexture.Left(), (GLfloat)PositionInTexture.Bottom()); 

		GLCheck(glEnd());

		//glEnable(GL_BLEND);
	}

} // namespace CasaEngine
